
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Jacob
 */
public class PaintPanel extends JPanel implements KeyListener, MouseMotionListener, MouseListener{
    public BufferedImage image;
    private Graphics graphics;
    private int penSize = 1;
    private int[] sizes = new int[]{1, 2, 3, 4, 5, 8, 12, 16, 20, 30};
    private PreviewPanel previewPanel;
    private JFrame previewFrame;
    private boolean isImage = false;
    public int size;
    private int width;
    private int height;
    private int mouseX;
    private int mouseY;
    private int mouseButton;
    public PaintPanel(File file)
    {
        if(file.getName().endsWith(".bmp") || file.getName().endsWith(".jpg") || file.getName().endsWith(".png") || file.getName().endsWith(".gif"))
            isImage = true;
        image = Bin2Img.doConvert(file);
        size = Bin2Img.size;
        graphics = image.createGraphics();
        this.width = image.getWidth();
        this.height = image.getHeight();
        this.setPreferredSize(new Dimension(width, height));
        this.addMouseListener(this);
        this.addKeyListener(this);
        this.addMouseMotionListener(this);
    }
    public void updatePreview()
    {
        if(isImage)
        {
            ByteArrayInputStream in = new ByteArrayInputStream(Img2Bin.getBytes(image, size));
            BufferedImage preview;
            try
            {
                preview = ImageIO.read(in);
            }
            catch(Exception ex)
            {
                return;
            }
            if(previewFrame == null)
            {
                previewFrame = new JFrame("Preview");
                previewPanel = new PreviewPanel();
                previewFrame.add(previewPanel);
                previewFrame.setVisible(true);
            }
            previewPanel.setImage(preview);
            previewFrame.pack();
        }
    }
    public void paint(Graphics g)
    {
        g.drawImage(image, 0, 0, null);
    }
    
    private void mouseDown(int x, int y, int b)
    {
        drawCircle(x, y, penSize, b);
        updatePreview();
    }
    
    private void drawCircle(int x, int y, int radius, int mode)
    {
        int drawX, drawY, sqRadius;
        sqRadius = radius*radius;
        for(drawX = -radius; drawX < radius; drawX++)
        {
            for(drawY = -radius; drawY < radius; drawY++)
            {
                if((drawX * drawX) + (drawY * drawY) <= sqRadius)
                {
                    int px = x + drawX;
                    int py = y + drawY;
                    if(px < 0 || py < 0 || px >= width || py >= height)
                        continue;
                    int rgb = image.getRGB(px, py);
                    int r = (rgb >>> 16) & 0xFF;
                    int g = (rgb >>> 8) & 0xFF;
                    int b = (rgb >>> 0) & 0xFF;
                    
                    switch(mode)
                    {
                        case 1:
                            r = (int) (Math.random() * 255);
                            g = (int) (Math.random() * 255);
                            b = (int) (Math.random() * 255);
                            break;
                        case 2:
                            r = (int) (r * 0.9);
                            g = (int) (g * 0.9);
                            b = (int) (b * 0.9);
                            break;
                        case 3:
                            int temp = r;
                            r = g;
                            g = temp;
                            break;
                    }
                    r = Math.min(Math.max(r, 0), 255);
                    g = Math.min(Math.max(g, 0), 255);
                    b = Math.min(Math.max(b, 0), 255);
                    graphics.setColor(new Color(r, g, b));
                    graphics.drawLine(px, py, px, py);
                }
            }
        }
        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        char c = e.getKeyChar();
        if(Character.isDigit(c))
        {
            int i = Integer.parseInt(c+"");
            if(i > 0)
                penSize = sizes[i-1];
        }
    }
    
    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void mouseDragged(MouseEvent e) {
        mouseDown(e.getX(), e.getY(), mouseButton);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        mouseX = e.getX();
        mouseY = e.getY();
    }

    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {
        mouseDown(e.getX(), e.getY(), e.getButton());
        mouseButton = e.getButton();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        this.grabFocus();
    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}
